import datetime

import jwt
from jwt.exceptions import *

from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission

from conf.config import JWT_TOKEN, JWT_EXPIRATION_DATE, ALGORITHM
from utils.response import DictResponse
from apps.user.models import SystemUser
from apps.system.models import SystemRolePermission, SystemPermission, SystemRole


# 设置jwt
def set_jwt(user_id):
	playload = {
		'sub': 'userInfo',
		'user_id': user_id,
		'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=JWT_EXPIRATION_DATE),
		'iat': datetime.datetime.utcnow()
	}
	return jwt.encode(playload, JWT_TOKEN, algorithm=ALGORITHM)


# 用户认证
class JWTAuthorization(BaseAuthentication):

	def authenticate(self, request):
		token = request.META.get('HTTP_AUTHORIZATION')
		try:
			decode_str = jwt.decode(token, key=JWT_TOKEN, algorithms=ALGORITHM)
		except ExpiredSignatureError:
			raise AuthenticationFailed(DictResponse(msg='签名过期错误'))
		except InvalidSignatureError:
			raise AuthenticationFailed(DictResponse(msg='无效的签名错误'))
		except InvalidAlgorithmError:
			raise AuthenticationFailed(DictResponse(msg='无效的算法错误'))
		except Exception:
			raise AuthenticationFailed(DictResponse(msg='认证失败'))
		return self.authenticate_credentials(decode_str), decode_str

	@staticmethod
	def authenticate_credentials(token):
		user = SystemUser.objects.filter(id=token.get('user_id'), status=True, deleted=False).first()
		if not user:
			raise AuthenticationFailed(DictResponse(msg='User inactive or deleted.'))
		return user


# 自定义权限
class IsHasPermission(BasePermission):

	# def has_object_permission(self, request, view, obj):
	# 	user = request.user
	# 	print(user)
	# 	return True

	def has_permission(self, request, view):
		role = request.user.role_id
		path = request.path

		if not SystemRole.objects.filter(deleted=False, status=True):
			raise AuthenticationFailed(DictResponse(msg='角色已删除或已停用'))
		# 公共权限
		public_permissions = SystemPermission.objects.filter(type='P', deleted=False)
		public_permission_path = [perm.url for perm in public_permissions]
		# 用户权限
		role_permissions = SystemRolePermission.objects.filter(role_id=role)
		user_has_permission_path = [perm.permission.url for perm in role_permissions]

		user_path_list = []
		for user_path in user_has_permission_path:
			if user_path.find(',') > 0:
				for p in user_path.split(','):
					user_path_list.append(p)
			else:
				user_path_list.append(user_path)
		if path in user_path_list or path in public_permission_path:
			return True
		else:
			raise AuthenticationFailed(DictResponse(msg='当前用户没有权限'))
